package com.webware.one.server.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.webware.one.shared.exception.AnyServiceException;
import com.webware.one.shared.exception.ValidationException;

@Repository
public abstract class AbstractDao<E /*extends AbstractEntity*/> {// implements
  // Dao<E> {

  public static final Logger log = Logger.getLogger(AbstractDao.class);

  public abstract Class<E> getEntityClass();

  @PersistenceContext
  protected EntityManager em;

  @Transactional
  public void persist(Object entity) throws AnyServiceException {
    log.debug(getEntityClass().getSimpleName() + " persist: ");
    try {
      em.persist(entity);
      em.flush();
      // System.out.println("id " + entity.getId());
    }
    catch (Exception e) {
      log.error("persist");
      throw new AnyServiceException(e.getMessage(), e);
    }
  }

  @Transactional
  public void remove(E entity) throws AnyServiceException {
    log.debug(getEntityClass().getSimpleName() + " remove: ");
    em.remove(entity);
  }

  @Transactional
  public void remove(Long id) throws AnyServiceException {
    log.debug(getEntityClass().getSimpleName() + " remove: " + id);
    em.remove(findById(id));
  }

  public E findById(Long id) {
    log.debug(getEntityClass().getSimpleName() + " findById: " + id);
    return em.find(getEntityClass(), id);
  }

  @SuppressWarnings("unchecked")
  public List<E> selectAll() throws AnyServiceException {
    log.debug(getEntityClass().getSimpleName() + " selectAll");
    Query q = em.createQuery("SELECT e FROM " + getEntityClass().getName() + " e");
    return q.getResultList();
  }

  public void assertLength(String string, int length) throws AnyServiceException  {
    if (string != null && string.length() > length)
      throw new ValidationException("Длина атрибута превышает максимальное значение " + length);
  }
}
